package com.zkh.myframe.server.tomcat.websocket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.zkh.myutils.io.log.Logger;
import com.zkh.myutils.json.JSON;
import com.zkh.myutils.utils.StringUtils;

/**
 * 工具类
 * @author zkh
 */
public class WebSocketUtils {
	
	/**
	 * 发送消息给指定用户
	 * @param branchId 分支编号
	 * @param sender 发送人。如果是在线聊天等一对一功能，需要传发送人，因为需要回复消息；如果是系统给指定用户推送消息，不需要用户回复，则无须指定该参数，置为null即可。
	 * @param message 消息内容
	 * @param args 附加参数。附加参数是为满足某些特殊需要而设计，用不上置为null即可。
	 * @param userKey 接收方用户标识
	 * @return 返回true表示消息已发送，false表示用户离线，未发送消息
	 */
	public static boolean sendMessage(String branchId, String sender, String message, Object args, String userKey){
		return sendMessage(branchId, sender,  message, args, Arrays.asList(userKey)).size()==0;
	}
	
	/**
	 * 发送消息给指定用户
	 * @param branchId 分支编号
	 * @param sender 发送人。如果是在线聊天等一对一功能，需要传发送人，因为需要回复消息；如果是系统给指定用户推送消息，不需要用户回复，则无须指定该参数，置为null即可。
	 * @param message 消息内容
	 * @param args 附加参数。附加参数是为满足某些特殊需要而设计，用不上置为null即可。
	 * @param userKeyList 接收方用户标识
	 * @return 返回离线用户列表。离线用户无法接收消息，故不会发送消息
	 */
	public static List<String> sendMessage(String branchId, String sender, String message, Object args, List<String> userKeyList) {
		//离线用户
		List<String> offlineUserList = new ArrayList<>();
		//接收用户不为空
		if(userKeyList!=null && userKeyList.size()>0) {
			//获取在线用户
			List<WebSocketCore> userSocketList = WebSocketSessionUtils.getWebSocketSessions(branchId, userKeyList, offlineUserList);
			//消息内容对象
			Map<String, Object> msgMap = new HashMap<>();
			//消息
			msgMap.put("message", message);
			//发送人
			if(StringUtils.isNotEmpty(sender)) {
				msgMap.put("sender", sender);
			}
			//附加参数
			if(args!=null) {
				msgMap.put("args", args);
			}
			//发送消息
			userSocketList.forEach(e->{
				try {
					e.sendMessage(JSON.getJSON(msgMap).toString());
				} catch (IOException e1) {
					e1.printStackTrace();
					Logger.error("消息发送失败：userKey=" + e.getUserKey());
				}
			});
		}
		//返回离线用户列表
		return offlineUserList;
	}
}
